package com.server.Tcp;

import com.server.utils.TcpSocket;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketTimeoutException;

import static com.server.Tcp.TcpTransitMsgString.transitMsg;

/**
 * 接收数据的线程
 */
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@Slf4j
public class ReceiveThread extends Thread{
    //添加volatile关键字使内存中的值刷新，否则循环中可能不刷新值
    private Socket client;
    //读出的数据
    private int len;
    //是否停止
    private volatile boolean stopThread;
    //输入流
    private BufferedInputStream bi;
    //输出流
    private BufferedOutputStream bo;

    //构造器
    public ReceiveThread(Socket socket){
        this.client=socket;
    }
    @Override
    public void run() {
        //获取该对象ip
        String ip=client.getInetAddress().getHostAddress();
        log.info("读线程启动");
        byte[] bytes=new byte[1024];
        try {
            bi = new BufferedInputStream(client.getInputStream());
            bo = new BufferedOutputStream(client.getOutputStream());
            while (true) {
                //判断是否停止线程
                if (stopThread){
                    stopThread=false;
                    break;
                }else {
                    try {
                        len = bi.read(bytes);
                        if (len==-1){
                            break;
                        }
                        System.out.println("本次接收到的数据为："+new String(bytes,0,len));
                        //分析发送过来的信息，如果正确调用发送方法
                        String[] calculate = TcpSocket.calculate(new String(bytes, 0, len));
                        if (calculate != null) {
                            transitMsg(calculate);
                        }
                    }catch (SocketTimeoutException e){
                        log.info("长时间未收到信息,开始发送心跳包判断连接是否断开");
                        try {
                            bo.write(0xff);
                            bo.flush();
                            log.info("心跳包发送成功,连接未断开");
                        }catch (IOException ignored){
                            log.info("心跳包发送失败，连接已断开");
                            break;
                        }
                    }
                }
            }
        }catch (IOException e) {
            //重置当前停止标志位
            stopThread=false;
            log.info("读线程停止");
        }finally {
            log.info("客户端"+ip+"断开连接");
            TcpSocket.closeSAndC(client,bi,bo);
            //当map里面的连接断开时，清除掉该对象
            TcpPool.clientMap.remove(ip);
            log.info("仍有"+TcpPool.clientMap.size()+"建立连接");
        }
    }
}
